package com.huike.aspectj;

import com.alibaba.fastjson.JSONObject;
import com.huike.common.annotation.Log;
import com.huike.domain.system.SysOperLog;
import com.huike.domain.system.dto.LoginUser;
import com.huike.service.ISysOperLogService;
import com.huike.utils.ip.AddressUtils;
import com.huike.utils.ip.IpUtils;
import com.huike.web.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

@Slf4j
@Aspect
@Component
public class OperaLogAspect {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ISysOperLogService iSysOperLogService;

//    @Around("execution(* com.huike.controller.*.*.*(..)) && @annotation(myLog)")
//    public Object LogAspect(ProceedingJoinPoint joinPoint, Log myLog) throws Throwable {
//        //将日志保存到数据库: sys_oper_log
//
//        Object result = null;
//        try {
//            //放行
//            result = joinPoint.proceed();
//            //记录正确日志
//            handleLog(joinPoint, myLog, result, null);
//        } catch (Throwable throwable) {
//            throwable.printStackTrace();
//            //记录错误日志
//            handleLog(joinPoint, myLog, null, throwable);
//            //将异常网上抛
//            throw new CustomException(throwable.getMessage());
//        }
//        return result;
//
//    }

    @AfterReturning(value = "execution(* com.huike.controller.*.*.*(..)) && @annotation(myLog)", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Log myLog, Object result) { //正常
        handleLog(joinPoint, myLog, result, null);  //记录日志
    }

    @AfterThrowing(value = "execution(* com.huike.controller.*.*.*(..)) && @annotation(myLog)", throwing = "throwable")
    public void afterthrowing(JoinPoint joinPoint, Log myLog, Throwable throwable) {    //异常
        handleLog(joinPoint, myLog, null, throwable);   //记录日志
    }

    //记录日志方法
    private void handleLog(JoinPoint joinPoint, com.huike.common.annotation.Log myLog, Object result, Throwable throwable) {

        //新建系统操作log对象
        SysOperLog sysOperLog = new SysOperLog();

        sysOperLog.setTitle(myLog.title());
        sysOperLog.setBusinessType(myLog.businessType().ordinal());
        sysOperLog.setMethod(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName());
        sysOperLog.setRequestMethod(request.getMethod()); //请求方式
        sysOperLog.setOperatorType(1);
        LoginUser loginUser = tokenService.getLoginUser(request);
        //user
        if (loginUser != null) {
            sysOperLog.setOperName(loginUser.getUser().getUserName());
            sysOperLog.setDeptName(loginUser.getUser().getUserName() != null ? loginUser.getUser().getDept().getDeptName() : null);
        }
        sysOperLog.setOperUrl(request.getRequestURI());
        //ip
        String ipAddr = IpUtils.getIpAddr(request);
        sysOperLog.setOperIp(ipAddr);
        //ip地址
        String location = AddressUtils.getRealAddressByIP(ipAddr);
        sysOperLog.setOperLocation(location);
        //参数
        sysOperLog.setOperParam(Arrays.toString(joinPoint.getArgs()));
        //返回值
        sysOperLog.setJsonResult(JSONObject.toJSONString(result));
        sysOperLog.setOperTime(new Date());
        sysOperLog.setStatus(0);
        //异常判断
        if (throwable != null) {
            sysOperLog.setStatus(1);
            sysOperLog.setErrorMsg(throwable.getMessage());
        }

        iSysOperLogService.insertOperlog(sysOperLog);
    }
}